package com.estore.network;

import com.estore.model.Product;
import com.estore.service.ProductService;
import java.io.*;
import java.net.*;
import java.util.List;

/**
 * 电商系统服务器
 * 处理客户端请求，管理商品数据和用户会话
 */
public class EStoreServer {
    private final ProductService productService;
    private final int port;
    private boolean running;

    public EStoreServer(int port) {
        this.port = port;
        this.productService = new ProductService();
        this.running = false;
    }

    public void start() {
        try (ServerSocket serverSocket = new ServerSocket(port)) {
            running = true;
            System.out.println("🟢 电商服务器已启动，监听端口: " + port);
            System.out.println("💾 数据文件: " + productService.getDataFilePath());
            System.out.println("🏪 当前商品数量: " + productService.getProductCount());

            while (running) {
                try {
                    Socket clientSocket = serverSocket.accept();
                    System.out.println("🔗 客户端连接: " + clientSocket.getInetAddress());

                    // 为每个客户端创建新线程处理
                    new ClientHandler(clientSocket, productService).start();

                } catch (IOException e) {
                    if (running) {
                        System.err.println("❌ 接受客户端连接失败: " + e.getMessage());
                    }
                }
            }
        } catch (IOException e) {
            System.err.println("❌ 启动服务器失败: " + e.getMessage());
        }
    }

    public void stop() {
        running = false;
        System.out.println("🛑 服务器正在关闭...");
    }

    public static void main(String[] args) {
        int port = 8888;
        if (args.length > 0) {
            try {
                port = Integer.parseInt(args[0]);
            } catch (NumberFormatException e) {
                System.err.println("无效的端口号，使用默认端口 8888");
            }
        }

        EStoreServer server = new EStoreServer(port);

        // 添加关闭钩子
        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
            server.stop();
            System.out.println("✅ 服务器已关闭");
        }));

        server.start();
    }
}

/**
 * 客户端请求处理线程
 */
class ClientHandler extends Thread {
    private final Socket clientSocket;
    private final ProductService productService;
    private ObjectInputStream input;
    private ObjectOutputStream output;

    public ClientHandler(Socket socket, ProductService productService) {
        this.clientSocket = socket;
        this.productService = productService;
    }

    @Override
    public void run() {
        try {
            // 注意：必须先创建输出流，再创建输入流
            output = new ObjectOutputStream(clientSocket.getOutputStream());
            output.flush(); // 刷新头部
            input = new ObjectInputStream(clientSocket.getInputStream());

            System.out.println("👤 开始处理客户端请求: " + clientSocket.getInetAddress());

            while (true) {
                try {
                    // 读取客户端请求
                    Object request = input.readObject();

                    if (request instanceof String) {
                        String command = (String) request;
                        System.out.println("📨 收到请求: " + command + " from " + clientSocket.getInetAddress());

                        // 处理请求
                        Object response = processRequest(command);

                        // 发送响应
                        output.writeObject(response);
                        output.flush();
                        System.out.println("📤 发送响应: " + (response instanceof List ? "List<Product>" : response));

                    } else {
                        System.err.println("❌ 未知请求类型: " + request.getClass());
                        output.writeObject("ERROR: Unknown request type");
                    }

                } catch (EOFException e) {
                    System.out.println("🔌 客户端断开连接: " + clientSocket.getInetAddress());
                    break;
                } catch (ClassNotFoundException e) {
                    System.err.println("❌ 反序列化失败: " + e.getMessage());
                    output.writeObject("ERROR: Deserialization failed");
                }
            }

        } catch (IOException e) {
            System.err.println("❌ 客户端处理错误: " + e.getMessage());
        } finally {
            closeConnection();
        }
    }

    /**
     *
     *
     * 处理客户端请求
     */
    private Object processRequest(String command) {
        try {
            switch (command) {
                case "GET_ALL_PRODUCTS":
                    return productService.getAllProducts();

                case "GET_PRODUCT_COUNT":
                    return productService.getProductCount();

                case "GET_PRODUCT_BY_ID":
                    try {
                        String productId = (String) input.readObject();
                        return productService.findProductById(productId);
                    } catch (Exception e) {
                        return "ERROR: " + e.getMessage();
                    }

                case "ADD_TO_CART":
                    try {
                        String cartProductId = (String) input.readObject();
                        int quantity = (Integer) input.readObject();
                        Product product = productService.findProductById(cartProductId);
                        if (product == null) {
                            return "ERROR: Product not found";
                        }
                        if (product.getStock() < quantity) {
                            return "ERROR: Insufficient stock";
                        }
                        return "SUCCESS: Added to cart";
                    } catch (Exception e) {
                        return "ERROR: " + e.getMessage();
                    }

                case "SEARCH_PRODUCTS":
                    try {
                        String keyword = (String) input.readObject();
                        List<Product> allProducts = productService.getAllProducts();
                        List<Product> results = allProducts.stream()
                                .filter(p -> p.getName().toLowerCase().contains(keyword.toLowerCase()) ||
                                        p.getId().toLowerCase().contains(keyword.toLowerCase()))
                                .toList();
                        return results;
                    } catch (Exception e) {
                        return "ERROR: " + e.getMessage();
                    }

                case "GET_IN_STOCK_PRODUCTS":
                    List<Product> inStockProducts = productService.getAllProducts().stream()
                            .filter(p -> p.getStock() > 0)
                            .toList();
                    return inStockProducts;

                case "BACKUP_DATA":
                    boolean backupResult = productService.backupData();
                    return backupResult ? "SUCCESS: Backup completed" : "ERROR: Backup failed";

                case "RESTORE_DATA":
                    boolean restoreResult = productService.restoreFromBackup();
                    return restoreResult ? "SUCCESS: Restore completed" : "ERROR: Restore failed";

                case "GET_BACKUP_INFO":
                    return productService.getBackupInfo();

                case "SAVE_DATA":
                    boolean saveResult = productService.saveData();
                    return saveResult ? "SUCCESS: Data saved" : "ERROR: Save failed";

                case "SHUTDOWN":
                    System.out.println("🛑 收到关闭服务器请求");
                    return "SUCCESS: Server shutting down";

                default:
                    return "ERROR: Unknown command: " + command;
            }
        } catch (Exception e) {
            return "ERROR: " + e.getMessage();
        }
    }

    private void closeConnection() {
        try {
            if (input != null) input.close();
            if (output != null) output.close();
            if (clientSocket != null) clientSocket.close();
            System.out.println("🔒 连接已关闭: " + clientSocket.getInetAddress());
        } catch (IOException e) {
            System.err.println("❌ 关闭连接时出错: " + e.getMessage());
        }
    }
}